home *** CD-ROM | disk | FTP | other *** search
- /*
- 3DS2POV.C Copyright (c) 1992 Steve Anger and Jeff Bowermaster
-
- Reads a 3DS ascii save file and writes a PoV DATa file
-
- Version 1.2 Written May 5/92
-
- Compiled with Borland C++ ver. 2.0
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "rayopt.h"
-
- #ifdef __TURBOC__
- extern unsigned _stklen = 16384; /* Large stack for recursion */
- #else
- #define huge
- #define far
- #define farmalloc(size) malloc(size)
- #define farfree(ptr) free(ptr)
- #endif
-
- #ifndef _GNUC_
- #include <malloc.h>
- #else
- #include <std.h>
- #endif
-
- #define MAX_MATERIAL 100
-
- #define POV 0
- #define RAW 1
-
- typedef struct
- {
- float x, y, z;
- }
- Vector;
-
-
- /* globals */
- char inname[80];
- char outname[80];
- float smooth;
- int bound;
- int verbose;
- int materials;
- int format;
- char *material[MAX_MATERIAL];
-
- /* Prototypes */
- void process_args (int argc, char *argv[]);
- void update_materials (char *new_material);
- void cleanup_name (char *name);
- char *before (char *str, char *target);
- char *after (char *str, char *target);
- char *between (char *str, char *target1, char *target2);
- char *strstr();
-
- int main (int argc, char *argv[])
- {
- int objects, vertices, faces, vertex_number, face_number, i,a,b,c;
- char parse, string[256], mtl[64], object[64];
- float x, y, z, tx, ty, tz, red, green, blue, lens;
- float gmin_x, gmin_y, gmin_z, gmax_x, gmax_y, gmax_z;
- Vector huge *coords = NULL;
- FILE *in, *out;
-
- process_args (argc, argv); /* Handle the command line args */
-
- if ((in = fopen (inname, "r")) == NULL) {
- printf ("Cannot open input file %s!\n", inname);
- exit (1);
- }
-
- if ((out = fopen (outname, "w")) == NULL) {
- printf ("Cannot open output file %s!\n", outname);
- exit (1);
- }
-
- if (format == POV) {
- opt_set_dec (4);
- opt_set_bound (bound);
- opt_set_smooth (smooth);
- opt_set_quiet (!verbose);
- opt_set_fname (outname, "");
- }
-
- objects = 0;
- vertices = 0;
- faces = 0;
- vertex_number = 0;
- face_number = 0;
- materials = 0;
-
- printf("Output to: %s\n",outname);
- printf("\nPlease wait; Processing...\n");
-
- if (format == POV) {
- fprintf (out, "#include \"colors.dat\"\n");
- fprintf (out, "#include \"shapes.dat\"\n");
- fprintf (out, "#include \"textures.dat\"\n\n");
- }
-
- while (fgets (string, 256, in) != NULL) {
- parse = string[0];
-
- switch (parse) {
- case 'A':
- /* Ambient light color: Red=0.3 Green=0.3 Blue=0.3 */
- /* Ignore for now */
- break;
-
- case 'B':
- /* Background solid color: Red=0 Green=0.105882 Blue=0.32549 */
- if (strstr (string, "Background solid") && format == POV) {
- red = atof (between (string, "Red=", "Green="));
- green = atof (between (string, "Green=", "Blue="));
- blue = atof (after (string, "Blue="));
-
- if (red > 0.0 || green > 0.0 || blue > 0.0) {
- fprintf (out, "/* Background colour */\n");
- fprintf (out, "object\n");
- fprintf (out, " sphere <0.0 0.0 0.0> 1e6 end_sphere\n");
- fprintf (out, " texture\n");
- fprintf (out, " ambient 1.0 diffuse 0.0\n");
- fprintf (out, " colour red %4.2f green %4.2f blue %4.2f\n",
- red, green, blue);
- fprintf (out, " end_texture\n");
- fprintf (out, "end_object\n\n");
- }
- }
-
- /* Bank angle: 0.00 degrees */
-
- /* Background dimmed */
-
- break;
-
- case 'C':
- /* Camera (50.000000mm) */
- if (strstr (string, "Camera") && format == POV) {
- lens = atof (between (string, "(", "mm)"));
-
- if (lens <= 0.0)
- lens = 16.0;
-
- fprintf(out,"view_point\n");
- fprintf(out," location <0.0 0.0 0.0>\n");
- }
-
- break;
-
- case 'D':
- /* Direct light */
- if (strstr (string, "Direct") && format == POV) {
- fprintf(out,"object\n");
- fprintf(out," sphere <0.0 0.0 0.0> 1.0 end_sphere\n");
- }
-
- /* Distance-cueing: */
-
- break;
-
- case 'F':
- /* Face 0: A:0 B:1 C:109 Mtl:CHROME */
- if (strstr (string, "Face") && strstr (string, "Mtl")) {
- face_number = atoi (between (string, "Face", ":"));
-
- a = atoi (between (string, "A:", "B:"));
- b = atoi (between (string, "B:", "C:"));
- c = atoi (between (string, "C:", "Mtl:"));
-
- strcpy (mtl, after (string, "Mtl:"));
- cleanup_name (mtl);
-
- if (format == POV) {
- update_materials (mtl);
-
- opt_set_texture (mtl);
- opt_add_tri (coords[a].x, coords[a].y, coords[a].z,
- coords[b].x, coords[b].y, coords[b].z,
- coords[c].x, coords[c].y, coords[c].z);
-
- if (face_number == faces-1) {
- fclose (out);
- opt_write_pov (object);
- out = fopen (outname, "a");
-
- ++objects;
-
- farfree ((void far *)coords);
- }
- }
- else if (format == RAW) {
- fprintf (out, "%f %f %f %f %f %f %f %f %f\n",
- coords[a].x, coords[a].y, coords[a].z,
- coords[b].x, coords[b].y, coords[b].z,
- coords[c].x, coords[c].y, coords[c].z);
- }
- }
-
- /* Face list: */
-
- /* Falloff size: 18.25 degrees */
-
- /* Far plane: 2113.823486 Far Dimming: 100 */
-
- break;
-
-
- case 'L':
- /* Light color: Red=0.32 Green=0.9 Blue=0.72 */
- if (strstr (string, "Light color") && format == POV) {
- red = atof (between (string, "Red=", "Green="));
- green = atof (between (string, "Green=", "Blue="));
- blue = atof (after (string, "Blue="));
-
- fprintf (out," colour red %4.2f green %4.2f blue %4.2f\n",red,green,blue);
- fprintf (out," texture\n");
- fprintf (out," ambient 1.0\n");
- fprintf (out," diffuse 0.0\n");
- fprintf (out," colour red %4.2f green %4.2f blue %4.2f\n",red,green,blue);
- fprintf (out," end_texture\n");
- fprintf (out," light_source\n");
- fprintf (out,"end_object\n\n");
- }
-
- break;
-
- case 'N':
- /* Named object: teacup */
- if (strstr (string, "Named")) {
- strcpy (object, after (string, ":"));
- cleanup_name (object);
- printf ("Working on: %s\n",object);
-
- if (format == RAW)
- fprintf (out, "; %s\n", object);
- }
-
- /* Near plane: 1728.713379 Near Dimming: 0 */
-
- break;
-
- case 'P':
- /* Position: X:298.177734 Y:-314.924225 Z:182.459198 */
- if (strstr (string, "Position") && format == POV) {
- x = atof (between (string, "X:", "Y:"));
- y = atof (between (string, "Y:", "Z:"));
- z = atof (after (string, "Z:"));
-
- fprintf (out," translate <%11.6f %11.6f %11.6f>\n", x,y,z);
- }
-
- break;
-
- case 'S':
- /* Smoothing: 1, 10 */
- /* don't know what it means */
-
- /* Spotlight to: X:-98.558777 Y:-176.971039 Z:-363.822357 */
- /* Could be synthesized, flaming terror */
-
- break;
-
-
- case 'T':
- /* Target: X:79.31871 Y:-11.135715 Z:27.661964 */
- if (strstr(string,"Target:") && format == POV) {
- tx = atof (between (string, "X:", "Y:"));
- ty = atof (between (string, "Y:", "Z:"));
- tz = atof (after (string, "Z:"));
-
- fprintf (out, " direction <0 %6.2f 0>\n", (lens/35.0));
- fprintf (out, " up <0 0 1>\n");
- fprintf (out, " sky <0 0 1>\n");
- fprintf (out, " right <1.33 0 0>\n");
- fprintf (out, " look_at <%11.6f %11.6f %11.6f>\n", tx,ty,tz);
- fprintf (out, "end_view_point\n\n");
- }
-
- /* Tri-mesh, Vertices: 3240 Faces: 6480 */
- if (strstr (string, "Tri-mesh")) {
- vertices = atoi (between (string, "Vertices:", "Faces:"));
- faces = atoi (after (string, "Faces:"));
-
- if ((coords = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
- abortmsg ("Insufficient memory for coordinates.", 1);
- }
-
- break;
-
- case 'V':
- /* Vertex 0: X: 82.320801 Y: -15.238132 Z: 28.071295 */
- if (strstr (string, "Vertex") && strstr (string, "X:")) {
- vertex_number = atoi (between (string, "Vertex", ":"));
-
- coords[vertex_number].x = atof (between (string, "X:", "Y:"));
- coords[vertex_number].y = atof (between (string, "Y:", "Z:"));
- coords[vertex_number].z = atof (after (string, "Z:"));
- }
-
- /* Vertex list: */
-
- break;
-
- default: /* Blank lines, page numbers... */
- break;
- }
- }
-
- if (format == POV) {
- for (i = 0; i < materials; i++) {
- fprintf (out, "#declare %s = texture\n", material[i]);
- fprintf (out, " DefTexture\n");
- fprintf (out, " color White\n");
- fprintf (out, "end_texture\n\n");
-
- free (material[i]);
- }
-
- fprintf (out, "composite /* All Objects */\n ");
-
- fclose (out);
- opt_finish();
- out = fopen (outname, "a");
-
- if (out == NULL)
- abortmsg ("Error opening output file", 1);
-
- opt_get_glimits (&gmin_x, &gmin_y, &gmin_z, &gmax_x, &gmax_y, &gmax_z);
-
- if (objects > 2) {
- fprintf (out, "\n");
- fprintf (out, " bounded_by\n");
- fprintf (out, "\tintersection\n");
- fprintf (out, "\t plane <+1 0 0> %.4f end_plane\n", +gmax_x);
- fprintf (out, "\t plane <-1 0 0> %.4f end_plane\n", -gmin_x);
- fprintf (out, "\t plane <0 +1 0> %.4f end_plane\n", +gmax_y);
- fprintf (out, "\t plane <0 -1 0> %.4f end_plane\n", -gmin_y);
- fprintf (out, "\t plane <0 0 +1> %.4f end_plane\n", +gmax_z);
- fprintf (out, "\t plane <0 0 -1> %.4f end_plane\n", -gmin_z);
- fprintf (out, "\tend_intersection\n");
- fprintf (out, " end_bound\n");
- }
-
- fprintf (out, "\n");
- fprintf (out, " /*\n");
- fprintf (out, " Scene extents\n");
- fprintf (out, " X - Min: %8.4f Max: %8.4f\n", gmin_x, gmax_x);
- fprintf (out, " Y - Min: %8.4f Max: %8.4f\n", gmin_y, gmax_y);
- fprintf (out, " Z - Min: %8.4f Max: %8.4f\n", gmin_z, gmax_z);
- fprintf (out, " */\n");
-
- fprintf (out, "end_composite\n\n");
- }
-
- fclose(in);
- fclose(out);
-
- return 0;
- }
-
-
-
- void process_args (int argc, char *argv[])
- {
- int i;
-
- printf("\n\nAutoDesk 3D Studio to PoV .DATa file Translator. May/92\n");
- printf("Version 1.2 Copyright (c) 1992 Steve Anger and Jeff Bowermaster\n");
- printf ("\n");
-
- if (argc < 2) {
- printf ("Usage: 3ds2pov inputfile[.asc] [outputfile[.dat]] [[-/]options]\n\n");
- printf ("Options: -snnn - Smooth triangles with angles < nnn\n");
- printf (" -b - Use box as bounding shape instead of ellipsoid.\n");
- printf (" -u - Do not add nested bounds to output (unbounded)\n");
- printf (" -v - Verbose status messages\n");
- printf (" -r - Output to RAW triangle format\n");
- printf ("\nex. 3ds2pov birdshow.asc birdshow.dat -s60 -v\n\n");
- exit(1);
- }
-
- strcpy (inname, "");
- strcpy (outname, "");
- smooth = 0.0;
- bound = 0;
- verbose = 0;
- format = POV;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-' || argv[i][0] == '/') {
- switch (argv[i][1]) {
- case 'B':
- case 'b': bound = 1;
- break;
-
- case 'R':
- case 'r': format = RAW;
- break;
-
- case 'U':
- case 'u': bound = 2;
- break;
-
- case 'V':
- case 'v': verbose = 1;
- break;
-
- case 'S':
- case 's': if (argv[i][2] == '\0')
- smooth = 60.0;
- else
- sscanf (&argv[i][2], "%f", &smooth);
- break;
-
- default : printf ("\nInvalid option -%c\n", argv[i][1]);
- exit (1);
- }
- }
- else if (strlen (inname) == 0) {
- strcpy (inname, argv[i]);
- add_ext (inname, "asc", 0);
- }
- else if (strlen (outname) == 0) {
- strcpy (outname, argv[i]);
-
- switch (format) {
- case POV: add_ext (outname, "dat", 0); break;
- case RAW: add_ext (outname, "raw", 0); break;
- }
- }
- else
- abortmsg ("Too many file names specified.\n", 1);
- }
-
- if (strlen(outname) == 0) {
- strcpy (outname, inname);
-
- switch (format) {
- case POV: add_ext (outname, "dat", 1); break;
- case RAW: add_ext (outname, "raw", 1); break;
- }
- }
- }
-
-
- void update_materials (char *new_material)
- {
- int i;
-
- for (i = 0; i < materials; i++) {
- if (strcmp (new_material, material[i]) == 0)
- break;
- }
-
- if (i < materials)
- return;
-
- if (i == MAX_MATERIAL)
- abortmsg ("Too many materials", 1);
-
- material[i] = malloc (strlen (new_material) + 1);
- strcpy (material[i], new_material);
-
- ++materials;
- }
-
-
- char *before (char *str, char *target)
- {
- static char result[256];
- char *search;
-
- strncpy (result, str, 256);
- result[255] = '\0';
-
- search = strstr (result, target);
-
- if (search != NULL)
- *search = '\0';
-
- return result;
- }
-
-
- char *after (char *str, char *target)
- {
- static char result[256];
- char *search;
-
- search = strstr (str, target);
-
- if (search == NULL)
- strncpy (result, "", 256);
- else
- strncpy (result, search + strlen(target), 256);
-
- result[255] = '\0';
-
- return result;
- }
-
-
- char *between (char *str, char *target1, char *target2)
- {
- static char result[256];
-
- strcpy (result, after (str, target1));
- strcpy (result, before (result, target2));
-
- return result;
- }
-
-